import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:math';

import 'package:flutter/foundation.dart';
import 'package:flutter_settings_screens/flutter_settings_screens.dart';
import 'package:geolocator/geolocator.dart';
import 'package:flutter/material.dart';
import 'package:macless_haystack/accessory/accessory_list_item.dart';
import 'package:macless_haystack/preferences/user_preferences_model.dart';
import 'package:latlong2/latlong.dart';
import 'package:logger/logger.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:http/http.dart' as http;

import 'package:macless_haystack/location/place_info.dart';

/// 解析第一个 MultiPolygon 特征的所有多边形坐标点
List<List<List<double>>> parseMultiPolygon(Map<String, dynamic> geoJson) {
  List<List<List<double>>> polygons = [];

  if (geoJson['type'] == 'FeatureCollection') {
    var features = geoJson['features'] as List;

    for (var feature in features) {
      var geometry = feature['geometry'];
      if (geometry != null && geometry['type'] == 'MultiPolygon') {
        List multiPolygonCoords = geometry['coordinates'];

        for (var polygon in multiPolygonCoords) {
          // polygon 是 List<List<double>>，格式是 [ [lon, lat], [lon, lat], ....]
          // 转换为 List<List<double>>, 并且换成 [lat, lon] 方便计算
          List<List<double>> polyPoints = polygon[0].map<List<double>>((point) {
            double lon = point[0];
            double lat = point[1];
            return [lat, lon];
          }).toList();

          polygons.add(polyPoints);
        }
      } else if (geometry != null && geometry['type'] == 'Polygon') {
        // Polygon类型处理
        List polygonCoords = geometry['coordinates'];

        List<List<double>> polyPoints =
            polygonCoords[0].map<List<double>>((point) {
          double lon = point[0];
          double lat = point[1];
          return [lat, lon];
        }).toList();

        polygons.add(polyPoints);
      }
    }
  }

  return polygons;
}

List<List<List<double>>>? chinaPolygons = parseMultiPolygon({
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "featurecla": "Admin-0 country",
        "scalerank": 1,
        "labelrank": 2,
        "sovereignt": "China",
        "sov_a3": "CH1",
        "adm0_dif": 1,
        "level": 2,
        "type": "Country",
        "tlc": "1",
        "admin": "China",
        "adm0_a3": "CHN",
        "geou_dif": 0,
        "geounit": "China",
        "gu_a3": "CHN",
        "su_dif": 0,
        "subunit": "China",
        "su_a3": "CHN",
        "brk_diff": 0,
        "name": "China",
        "name_long": "China",
        "brk_a3": "CHN",
        "brk_name": "China",
        "brk_group": null,
        "abbrev": "China",
        "postal": "CN",
        "formal_en": "People's Republic of China",
        "formal_fr": null,
        "name_ciawf": "China",
        "note_adm0": null,
        "note_brk": null,
        "name_sort": "China",
        "name_alt": null,
        "mapcolor7": 4,
        "mapcolor8": 4,
        "mapcolor9": 4,
        "mapcolor13": 3,
        "pop_est": 1397715000,
        "pop_rank": 18,
        "pop_year": 2019,
        "gdp_md": 14342903,
        "gdp_year": 2019,
        "economy": "3. Emerging region: BRIC",
        "income_grp": "3. Upper middle income",
        "fips_10": "CH",
        "iso_a2": "CN",
        "iso_a2_eh": "CN",
        "iso_a3": "CHN",
        "iso_a3_eh": "CHN",
        "iso_n3": "156",
        "iso_n3_eh": "156",
        "un_a3": "156",
        "wb_a2": "CN",
        "wb_a3": "CHN",
        "woe_id": 23424781,
        "woe_id_eh": 23424781,
        "woe_note": "Exact WOE match as country",
        "adm0_iso": "CHN",
        "adm0_diff": null,
        "adm0_tlc": "CHN",
        "adm0_a3_us": "CHN",
        "adm0_a3_fr": "CHN",
        "adm0_a3_ru": "CHN",
        "adm0_a3_es": "CHN",
        "adm0_a3_cn": "CHN",
        "adm0_a3_tw": "TWN",
        "adm0_a3_in": "CHN",
        "adm0_a3_np": "CHN",
        "adm0_a3_pk": "CHN",
        "adm0_a3_de": "CHN",
        "adm0_a3_gb": "CHN",
        "adm0_a3_br": "CHN",
        "adm0_a3_il": "CHN",
        "adm0_a3_ps": "CHN",
        "adm0_a3_sa": "CHN",
        "adm0_a3_eg": "CHN",
        "adm0_a3_ma": "CHN",
        "adm0_a3_pt": "CHN",
        "adm0_a3_ar": "CHN",
        "adm0_a3_jp": "CHN",
        "adm0_a3_ko": "CHN",
        "adm0_a3_vn": "CHN",
        "adm0_a3_tr": "CHN",
        "adm0_a3_id": "CHN",
        "adm0_a3_pl": "CHN",
        "adm0_a3_gr": "CHN",
        "adm0_a3_it": "CHN",
        "adm0_a3_nl": "CHN",
        "adm0_a3_se": "CHN",
        "adm0_a3_bd": "CHN",
        "adm0_a3_ua": "CHN",
        "adm0_a3_un": -99,
        "adm0_a3_wb": -99,
        "continent": "Asia",
        "region_un": "Asia",
        "subregion": "Eastern Asia",
        "region_wb": "East Asia & Pacific",
        "name_len": 5,
        "long_len": 5,
        "abbrev_len": 5,
        "tiny": -99,
        "homepart": 1,
        "min_zoom": 0,
        "min_label": 1.7,
        "max_label": 5.7,
        "label_x": 106.337289,
        "label_y": 32.498178,
        "ne_id": 1159320471,
        "wikidataid": "Q148",
        "name_ar": "الصين",
        "name_bn": "গণচীন",
        "name_de": "Volksrepublik China",
        "name_en": "People's Republic of China",
        "name_es": "China",
        "name_fa": "جمهوری خلق چین",
        "name_fr": "République populaire de Chine",
        "name_el": "Λαϊκή Δημοκρατία της Κίνας",
        "name_he": "הרפובליקה העממית של סין",
        "name_hi": "चीनी जनवादी गणराज्य",
        "name_hu": "Kína",
        "name_id": "Republik Rakyat Tiongkok",
        "name_it": "Cina",
        "name_ja": "中華人民共和国",
        "name_ko": "중화인민공화국",
        "name_nl": "Volksrepubliek China",
        "name_pl": "Chińska Republika Ludowa",
        "name_pt": "China",
        "name_ru": "Китайская Народная Республика",
        "name_sv": "Kina",
        "name_tr": "Çin Halk Cumhuriyeti",
        "name_uk": "Китайська Народна Республіка",
        "name_ur": "عوامی جمہوریہ چین",
        "name_vi": "Trung Quốc",
        "name_zh": "中华人民共和国",
        "name_zht": "中華人民共和國",
        "fclass_iso": "Admin-0 country",
        "tlc_diff": null,
        "fclass_tlc": "Admin-0 country",
        "fclass_us": null,
        "fclass_fr": null,
        "fclass_ru": null,
        "fclass_es": null,
        "fclass_cn": null,
        "fclass_tw": "Unrecognized",
        "fclass_in": null,
        "fclass_np": null,
        "fclass_pk": null,
        "fclass_de": null,
        "fclass_gb": null,
        "fclass_br": null,
        "fclass_il": null,
        "fclass_ps": null,
        "fclass_sa": null,
        "fclass_eg": null,
        "fclass_ma": null,
        "fclass_pt": null,
        "fclass_ar": null,
        "fclass_jp": null,
        "fclass_ko": null,
        "fclass_vn": null,
        "fclass_tr": null,
        "fclass_id": null,
        "fclass_pl": null,
        "fclass_gr": null,
        "fclass_it": null,
        "fclass_nl": null,
        "fclass_se": null,
        "fclass_bd": null,
        "fclass_ua": null,
        "filename": "CHN.geojson"
      },
      "geometry": {
        "type": "MultiPolygon",
        "coordinates": [
          [
            [
              [109.47520958866365, 18.197700913968575],
              [108.65520796105616, 18.507681993071387],
              [108.62621748254044, 19.367887885001906],
              [109.11905561730804, 19.821038519769345],
              [110.21159874882281, 20.101253973872033],
              [110.78655073450221, 20.077534491450052],
              [111.01005130416458, 19.69592987719072],
              [110.57064660038677, 19.25587921800927],
              [110.33918786015147, 18.678395087147592],
              [109.47520958866365, 18.197700913968575]
            ]
          ],
          [
            [
              [80.2599902688853, 42.34999929459906],
              [80.1801501809943, 42.92006785742694],
              [80.86620649610126, 43.18036204688101],
              [79.96610639844141, 44.91751699480463],
              [81.9470707539181, 45.31702749285312],
              [82.45892581576906, 45.539649563166506],
              [83.18048383986047, 47.33003123635086],
              [85.16429039911324, 47.0009557155161],
              [85.72048383987067, 47.452969468773105],
              [85.7682328633083, 48.45575063739699],
              [86.59877648310336, 48.549181626980626],
              [87.35997033076265, 49.21498078062912],
              [87.75126427607671, 49.297197984405486],
              [88.01383222855173, 48.599462795600616],
              [88.85429772334676, 48.069081732772965],
              [90.28082563676392, 47.69354909930793],
              [90.97080936072501, 46.88814606382293],
              [90.58576826371828, 45.71971609148753],
              [90.9455395853343, 45.28607330991028],
              [92.13389082231822, 45.11507599545646],
              [93.4807336771413, 44.975472113619965],
              [94.68892866412533, 44.35233185482842],
              [95.30687544147153, 44.24133087826547],
              [95.76245486855669, 43.319449164394605],
              [96.34939578652781, 42.725635280928685],
              [97.45175744017801, 42.74888967546002],
              [99.51581749878004, 42.524691473961724],
              [100.84586551310827, 42.66380442969145],
              [101.83304039917994, 42.51487295182628],
              [103.31227827353482, 41.9074681666676],
              [104.52228193564899, 41.908346666016556],
              [104.96499393109347, 41.59740957291635],
              [106.12931562706169, 42.13432770442891],
              [107.74477257693795, 42.48151581478187],
              [109.24359581913146, 42.5194463160841],
              [110.41210330611528, 42.87123362891103],
              [111.12968224492023, 43.40683401140015],
              [111.82958784388137, 43.74311839453952],
              [111.66773725794323, 44.07317576758771],
              [111.34837690637946, 44.45744171811009],
              [111.8733061056003, 45.10207937273506],
              [112.43606245325881, 45.01164561622429],
              [113.46390669154417, 44.80889313412712],
              [114.46033165899607, 45.339816799493825],
              [115.98509647020009, 45.727235012386004],
              [116.71786828009886, 46.38820241961521],
              [117.42170128791419, 46.67273285581426],
              [118.87432579963873, 46.80541209572365],
              [119.66326989143876, 46.69267995867892],
              [119.7728239278975, 47.04805878355013],
              [118.86657433479495, 47.74706004494617],
              [118.06414269416672, 48.06673045510369],
              [117.29550744025741, 47.69770905210743],
              [116.30895267137323, 47.85341014260284],
              [115.74283735561579, 47.72654450132629],
              [115.48528201707306, 48.13538259540344],
              [116.19180219936757, 49.134598090199106],
              [116.67880089728612, 49.888531399121405],
              [117.8792444194264, 49.510983384796965],
              [119.2884607280258, 50.142882798862004],
              [119.27939, 50.58292],
              [120.18208000000016, 51.64355000000012],
              [120.7382, 51.96411],
              [120.72578901579197, 52.516226304730935],
              [120.17708865771681, 52.75388621684124],
              [121.00308475147017, 53.25140106873119],
              [122.24574791879283, 53.431725979213695],
              [123.57147, 53.4588],
              [125.06821129771038, 53.16104482686886],
              [125.94634891164617, 52.79279857035698],
              [126.56439904185697, 51.7842554795327],
              [126.93915652883766, 51.35389415140592],
              [127.28745568248485, 50.73979726826548],
              [127.65740000000028, 49.760270000000105],
              [129.39781782442043, 49.44060008401544],
              [130.58229332898242, 48.72968740497614],
              [130.9872600000001, 47.79013],
              [132.50669, 47.78896],
              [133.37359581922794, 48.18344167743487],
              [135.02631147678665, 48.478229885443874],
              [134.50081, 47.57845],
              [134.1123500000001, 47.21248],
              [133.76964399631288, 46.116926988299014],
              [133.09712000000013, 45.14409],
              [131.8834542176595, 45.32116160743652],
              [131.02519000000018, 44.96796],
              [131.28855512911548, 44.11151968034828],
              [131.1446879416149, 42.92998973242689],
              [130.63386640840974, 42.90301463477053],
              [130.63999970690955, 42.39502427522179],
              [129.99426720593323, 42.985386867843786],
              [129.59666873587952, 42.42498179785456],
              [128.0522152039723, 41.99428457291795],
              [128.20843305879066, 41.46677155208249],
              [127.34378299368302, 41.50315176041597],
              [126.86908328664987, 41.81656932226619],
              [126.18204511932943, 41.10733612727637],
              [125.07994184784064, 40.56982371679245],
              [124.26562462778531, 39.928493353834156],
              [122.86757042856095, 39.63778758397622],
              [122.1313879741309, 39.170451768544666],
              [121.05455447803286, 38.897471014962846],
              [121.58599490772248, 39.36085358332407],
              [121.37675703337268, 39.75026133885949],
              [122.16859500538106, 40.422442531896024],
              [121.64035851449353, 40.94638987890333],
              [120.76862877816194, 40.59338816991754],
              [119.63960208544907, 39.898055935214245],
              [119.02346398323306, 39.252333075511146],
              [118.04274865119791, 39.2042739934797],
              [117.53270226447711, 38.73763580988408],
              [118.05969852098964, 38.06147553156106],
              [118.87814985562832, 37.89732534438593],
              [118.91163618375344, 37.44846385349871],
              [119.70280236214205, 37.15638865818505],
              [120.8234574728236, 37.87042776137801],
              [121.711258579598, 37.48112335870718],
              [122.35793745329849, 37.45448415786072],
              [122.5199947449658, 36.93061432550185],
              [121.10416385303307, 36.651329047180425],
              [120.63700890511453, 36.111439520811075],
              [119.66456180224606, 35.60979055433772],
              [119.1512081238586, 34.90985911716044],
              [120.22752485563373, 34.36033193616865],
              [120.62036909391655, 33.37672272392514],
              [121.22901411345023, 32.46031871187719],
              [121.90814578663003, 31.692174384074647],
              [121.89191938689038, 30.949351508095106],
              [121.26425744027328, 30.6762674016487],
              [121.50351932178467, 30.14291494396429],
              [122.0921138855891, 29.83252045340315],
              [121.93842817595306, 29.01802236583478],
              [121.68443851123851, 28.225512600206617],
              [121.12566124886649, 28.135673122667185],
              [120.39547326058232, 27.05320689544932],
              [119.5854968608395, 25.740780544532612],
              [118.65687137255452, 24.54739085540024],
              [117.28160647997088, 23.624501451099658],
              [115.89073530483512, 22.78287323657807],
              [114.76382734584624, 22.668074042241667],
              [114.15254682826564, 22.22376007739615],
              [113.80677981980074, 22.5483397486214],
              [113.24107791550159, 22.051367499270455],
              [111.84359215703248, 21.550493679281473],
              [110.78546552942407, 21.397143866455338],
              [110.44403934127168, 20.34103261970633],
              [109.88986128137361, 20.282457383703488],
              [109.62765506392466, 21.008227037026703],
              [109.86448815311832, 21.395050970947523],
              [108.5228129415244, 21.715212307211814],
              [108.05018029178294, 21.55237986906012],
              [107.04342003787264, 21.811898912029914],
              [106.56727339073532, 22.21820486092477],
              [106.72540327354847, 22.79426788989842],
              [105.81124718630522, 22.976892401617903],
              [105.32920942588663, 23.352063300056912],
              [104.47685835166448, 22.819150092046968],
              [103.50451460166056, 22.70375661873921],
              [102.7069922221001, 22.708795070887675],
              [102.17043582561358, 22.464753119389304],
              [101.65201785686152, 22.318198757409547],
              [101.80311974488293, 21.17436676684507],
              [101.27002566935997, 21.201651923095184],
              [101.18000532430754, 21.436572984294028],
              [101.15003299357825, 21.849984442629022],
              [100.41653771362738, 21.558839423096614],
              [99.98348921102149, 21.7429367131364],
              [99.24089887898725, 22.11831431730458],
              [99.5319922220874, 22.94903880461258],
              [98.89874922078278, 23.14272207284253],
              [98.66026248575577, 24.063286037689966],
              [97.60471967976198, 23.897404690033042],
              [97.72460900267914, 25.083637193293],
              [98.67183800658916, 25.918702500913525],
              [98.71209394734451, 26.743535874940267],
              [98.68269005737046, 27.50881216075062],
              [98.2462309102333, 27.74722138112918],
              [97.91198774616944, 28.335945136014345],
              [97.32711388549004, 28.26158274994634],
              [96.24883344928779, 28.411030992134442],
              [96.58659061074749, 28.83097951915434],
              [96.11767866413103, 29.452802028922466],
              [95.40480228066464, 29.03171662039213],
              [94.56599043170294, 29.277438055939985],
              [93.41334760943269, 28.640629380807226],
              [92.50311893104364, 27.89687632904645],
              [91.69665652869668, 27.771741848251665],
              [91.25885379431992, 28.040614325466294],
              [90.7305139505678, 28.064953925075756],
              [90.01582889197118, 28.296438503527217],
              [89.47581017452111, 28.042758897406397],
              [88.81424848832056, 27.299315904239364],
              [88.73032596227856, 28.086864732367516],
              [88.12044070836987, 27.876541652939594],
              [86.9545170430006, 27.974261786403517],
              [85.82331994013151, 28.203575954698707],
              [85.01163821812304, 28.642773952747344],
              [84.23457970575015, 28.839893703724698],
              [83.89899295444673, 29.320226141877658],
              [83.33711510613719, 29.463731594352197],
              [82.32751264845088, 30.115268052688137],
              [81.52580447787474, 30.42271698660863],
              [81.11125613802932, 30.183480943313402],
              [79.7213668151071, 30.88271474865473],
              [78.73889448437401, 31.515906073527063],
              [78.45844648632601, 32.61816437431273],
              [79.17612877799553, 32.48377981213771],
              [79.20889163606859, 32.994394639613716],
              [78.81108646028574, 33.50619802503242],
              [78.91226891471322, 34.32193634697579],
              [77.83745079947457, 35.494009507787766],
              [76.19284834178569, 35.89840342868783],
              [75.89689741405013, 36.666806138651836],
              [75.15802778514092, 37.13303091078912],
              [74.98000247589542, 37.419990139305895],
              [74.8299857929521, 37.9900070257014],
              [74.86481570831683, 38.3788463404816],
              [74.25751427602273, 38.60650686294345],
              [73.92885216664644, 38.50581533462274],
              [73.6753792662548, 39.4312368841056],
              [73.96001305531843, 39.660008449861735],
              [73.8222436868283, 39.893973497063186],
              [74.77686242055606, 40.36642527929163],
              [75.4678279967307, 40.56207225194867],
              [76.52636803579745, 40.42794607193512],
              [76.90448449087708, 41.06648590754965],
              [78.18719689322597, 41.18531586360481],
              [78.54366092317531, 41.58224254003869],
              [80.11943037305139, 42.12394074153825],
              [80.2599902688853, 42.34999929459906]
            ]
          ]
        ]
      }
    }
  ]
});

bool isPointInPolygon(List<List<double>> polygon, double lat, double lon) {
  // Check if polygon has at least 3 points (a valid polygon)
  if (polygon.length < 3) return false;

  bool inside = false;
  int j = polygon.length - 1;

  for (int i = 0; i < polygon.length; i++) {
    // Get current and previous points
    final double xi = polygon[i][0], yi = polygon[i][1];
    final double xj = polygon[j][0], yj = polygon[j][1];

    // Check if point is exactly on a vertex
    if (xi == lat && yi == lon) return true;

    // Check if point is on the edge between i and j
    if ((yi == yj) && (yi == lon)) {
      if ((xi <= lat && lat <= xj) || (xj <= lat && lat <= xi)) {
        return true;
      }
    }

    // Ray casting intersection check
    if ((yi > lon) != (yj > lon)) {
      final double intersectX = (xj - xi) * (lon - yi) / (yj - yi) + xi;
      if (lat <= intersectX) {
        inside = !inside;
      }
    }

    j = i;
  }

  return inside;
}

class LocationModel extends ChangeNotifier {
  LatLng? here;
  // geocode.Placemark? herePlace;
  Placeinfo? herePlace;
  // StreamSubscription<LocationData>? locationStream;
  StreamSubscription<Position>? locationStream;
  bool initialLocationSet = false;
  //Location location = Location();

  var logger = Logger(
    printer: PrettyPrinter(methodCount: 0),
  );

  /// Requests access to the device location from the user.
  ///
  /// Initializes the location services and requests location
  /// access from the user if not granged.
  /// Returns if location access was granted.
  Future<bool> requestLocationAccess() async {
    bool serviceEnabled;
    LocationPermission permissionGranted;

    serviceEnabled = await Geolocator.isLocationServiceEnabled();
    if (!serviceEnabled) {
      /*serviceEnabled = await location.requestService();
      if (!serviceEnabled) {
        return false;
      }*/
      openAppSettings();
      return false;
    }
    if (await Permission.location.isPermanentlyDenied) {
      openAppSettings();
      return false;
    }

    permissionGranted = await Geolocator.checkPermission();
    if (permissionGranted == LocationPermission.denied) {
      permissionGranted = await Geolocator.requestPermission();
      if (permissionGranted == LocationPermission.denied ||
          permissionGranted == LocationPermission.deniedForever) {
        return false;
      }
    }

    return true;
  }

  /// Requests location updates from the platform.
  ///
  /// Listeners will be notified about location changes.
  Future<void> requestLocationUpdates() async {
    var permissionGranted = await requestLocationAccess();
    if (permissionGranted) {
      // Handle future location updates
      // locationStream ??= location.onLocationChanged.listen(_updateLocation);
      locationStream ??= Geolocator.getPositionStream().listen((Position pos) {
        _updateLocation(pos, reGeo: false);
      });

      //var locationData = await location.getLocation();
      var locationData = await Geolocator.getCurrentPosition();

      // Fetch the current location
      if (locationData != null) _updateLocation(locationData);
    } else {
      initialLocationSet = true;
      if (locationStream != null) {
        locationStream?.cancel();
        locationStream = null;
      }
      _removeCurrentLocation();
      notifyListeners();
    }
  }

  /// Updates the current location if new location data is available.
  ///
  /// Additionally updates the current address information to match
  /// the new location.
  void _updateLocation(Position locationData, {bool reGeo = true}) {
    if (locationData.latitude != null && locationData.longitude != null) {
      logger.d(
          'Location here: ${locationData.latitude!}, ${locationData.longitude!}');

      here = LatLng(locationData.latitude!, locationData.longitude!);
      initialLocationSet = true;
      if (reGeo) {
        reGeoCode(wgs84ToGcj02(here!)).then((value) {
          herePlace = value;
          notifyListeners();
        });
      } else {
        notifyListeners();
      }
    } else {
      logger.e('Received invalid location data: $locationData');
    }
    notifyListeners();
  }

  /// Cancels the listening for location updates.
  void cancelLocationUpdates() {
    if (locationStream != null) {
      locationStream?.cancel();
      locationStream = null;
    }
    _removeCurrentLocation();
    notifyListeners();
  }

  /// Resets the currently stored location and address information
  void _removeCurrentLocation() {
    here = null;
    herePlace = null;
  }

  /// Returns the address for a given geolocation (latitude & longitude).
  ///
  /// Only works on mobile platforms with their local APIs.
  Future<Placeinfo?> getAddress(LatLng? location) async {
    if (location == null) {
      return null;
    }
    /*double lat = location.latitude;
    double lng = location.longitude;

    try {
      List<Placeinfo> placemarks =
          await geocode.placemarkFromCoordinates(lat, lng);
      return placemarks.first;
    } on MissingPluginException {
      return null;
    } on PlatformException {
      return null;
    }*/

    /*var convertedLocations = await convertCoordType([location]);
    if (convertedLocations != null) {
      var convertedLocation = convertedLocations[0];
      return reGeoCode(convertedLocation);
    }
    return null;*/
    var convertedLocation = wgs84ToGcj02(location);
    return reGeoCode(convertedLocation);
  }

  Future<Placeinfo?> reGeoCode(LatLng? location) async {
    if (location == null) {
      return null;
    }
    String amapKey = Settings.getValue<String>(amapWebApiKey, defaultValue: '')!.trim();
    String amapKeyFallback = Settings.getValue<String>(amapWebApiKeyFallback, defaultValue: '')!;
    if(amapKey == '') {
      amapKey = amapKeyFallback;
    }
    final response = await http.get(Uri.parse(
        'https://restapi.amap.com/v3/geocode/regeo?key=${amapKey}&location=${location.longitude},${location.latitude}'));

    if (response.statusCode == 200) {
      Map<String, dynamic> data = json.decode(response.body);
      if (data['status'] == '1') {
        var item = data['regeocode'];
        Map<String, dynamic> addcmp = item['addressComponent'];
        Map<String, dynamic>? streetcmp = item['streetNumber'];

        return Placeinfo.fromMap({
          'name': item['formatted_address'],
          'country': addcmp['country'],
          'city': addcmp['city'] is List && (addcmp['city'] as List).isEmpty
              ? ''
              : addcmp['city'],
          'province': addcmp['province'],
          'district':
              addcmp['district'] is List && (addcmp['district'] as List).isEmpty
                  ? ''
                  : addcmp['district'],
          'township':
              addcmp['township'] is List && (addcmp['township'] as List).isEmpty
                  ? ''
                  : addcmp['township'],
          'street': streetcmp != null
              ? streetcmp['street'] is List &&
                      (streetcmp['street'] as List).isEmpty
                  ? ''
                  : streetcmp['street']
              : ''
        });
      }
    }
    return null;
  }

  /*Future<List<LatLng>?> convertCoordType(List<LatLng>? locations) async {
    if (locations == null || locations.isEmpty) {
      return null;
    }
    final response = await http.get(Uri.parse(
        'https://restapi.amap.com/v3/assistant/coordinate/convert?key=${amapKey}&coordsys=gps&locations=${locations.map((x) => '${x.longitude},${x.latitude}').join('|')}'));

    if (response.statusCode == 200) {
      Map<String, dynamic> data = json.decode(response.body);
      if (data['status'] == '1') {
        var str = data['locations'] as String;
        var arr = str.split(';').where((x) => x != '');

        return arr.map((x) {
          var ll = x.split(',');
          return LatLng(double.parse(ll[1]), double.parse(ll[0]));
        }).toList();
      }
    }
    return null;
  }*/

  // WGS84 to GCJ02
  LatLng? wgs84ToGcj02(LatLng? location) {
    if (location == null) {
      return null;
    }
    const double pi = 3.1415926535897932384626;
    const double a = 6378245.0; // 长半轴
    const double ee = 0.00669342162296594323; // 偏心率平方
    double dLat, dLon;

    double lat = location.latitude;
    double lon = location.longitude;

    if (!isInChina(lat, lon)) {
      return location; // 如果不在中国, 不转换
    }

    dLat = _transformLat(lon - 105.0, lat - 35.0);
    dLon = _transformLon(lon - 105.0, lat - 35.0);
    double radLat = lat / 180.0 * pi;
    double magic = sin(radLat);
    magic = 1 - ee * magic * magic;
    double sqrtMagic = sqrt(magic);
    dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
    dLon = (dLon * 180.0) / (a / sqrtMagic * cos(radLat) * pi);

    double mgLat = lat + dLat;
    double mgLon = lon + dLon;

    return LatLng(mgLat, mgLon);
  }

  bool isInChina(double lat, double lon) {
    if (chinaPolygons != null && chinaPolygons!.isNotEmpty) {
      return chinaPolygons!
          .any((polygon) => isPointInPolygon(polygon, lat, lon));
    }
    return lat >= 0.8293 && lat <= 55.8271 && lon >= 72.004 && lon <= 137.8347;
  }

  double _transformLat(double x, double y) {
    const double pi = 3.1415926535897932384626;
    double ret = -100.0 +
        2.0 * x +
        3.0 * y +
        0.2 * y * y +
        0.1 * x * y +
        0.2 * sqrt(x.abs());
    ret += (20.0 * sin(6.0 * x * pi) + 20.0 * sin(2.0 * x * pi)) * 2.0 / 3.0;
    ret += (20.0 * sin(y * pi) + 40.0 * sin(y / 3.0 * pi)) * 2.0 / 3.0;
    ret +=
        (160.0 * sin(y / 12.0 * pi) + 320.0 * sin(y * pi / 30.0)) * 2.0 / 3.0;
    return ret;
  }

  double _transformLon(double x, double y) {
    const double pi = 3.1415926535897932384626;
    double ret =
        300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * sqrt(x.abs());
    ret += (20.0 * sin(6.0 * x * pi) + 20.0 * sin(2.0 * x * pi)) * 2.0 / 3.0;
    ret += (20.0 * sin(x * pi) + 40.0 * sin(x / 3.0 * pi)) * 2.0 / 3.0;
    ret +=
        (150.0 * sin(x / 12.0 * pi) + 300.0 * sin(x / 30.0 * pi)) * 2.0 / 3.0;
    return ret;
  }
}
